﻿#region copyright
//Copyright (c) 2011, Check In Solutions LLC
//All rights reserved.

//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions are met:
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//    * Neither the name of the Check In Solutions LLC nor the
//      names of its contributors may be used to endorse or promote products
//      derived from this software without specific prior written permission.

//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//DISCLAIMED. IN NO EVENT SHALL CHECK IN SOLUTIONS LLC BE LIABLE FOR ANY
//DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
//ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
//using System.ComponentModel;

namespace CheckInSolutions.Messaging
{
    public class Serializer<T>  // where T : ICloneable, new()
    {
        #region Constructors
        /// <summary>
        /// Serialize and Deserialize object of type (T)
        /// </summary>
        /// <param name="t">object type (T)</param>
        public Serializer()
        {
            this.XmlSerializer = new XmlSerializer(typeof(T));
        }
        #endregion

        #region Enums
        #endregion

        #region Properties
        protected XmlSerializer m_XmlSerializer;
        /// <summary>
        /// Internal serializer for repeat calls
        /// </summary>
        protected XmlSerializer XmlSerializer
        {
            get { return this.m_XmlSerializer; }
            set { this.m_XmlSerializer = value; }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Returns an XML string serialization of the Object
        /// </summary>
        /// <exception cref="System.ArgumentException">The byte array contains invalid Unicode code points.</exception>
        /// <exception cref="System.ArgumentNullException">bytes is null.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">index or count is less than zero.-or- index and count do not denote a valid range in bytes.</exception>
        /// <exception cref="System.Text.DecoderFallbackException">A fallback occurred (see Understanding Encodings for complete explanation)-and-System.Text.Encoding.DecoderFallback is set to System.Text.DecoderExceptionFallback.</exception>
        /// <see cref="Encoding.UTF8.GetString"/>
        /// <param name="objToSerialize"></param>
        /// <returns>XML String</returns>
        public string serializetoString(T objToSerialize)

        {
            string xmlString = null;
            using (MemoryStream xmlStream = new MemoryStream())
            {
                using (TextWriter utf8Stream = new StreamWriter(xmlStream))
                {
                    //T myObj = objToSerialize;
                    //if (!myObj.GetType().Equals(objToSerialize))
                    //{
                    //    myObj = (T)objToSerialize.Clone();
                    //}
                    //Boolean b = myObj.GetType().Equals(objToSerialize);

                    this.XmlSerializer.Serialize(utf8Stream, objToSerialize);
                    xmlString = Encoding.UTF8.GetString(xmlStream.GetBuffer(), 0, (int)xmlStream.Length);
                    xmlStream.Close();
                    utf8Stream.Close();
                }
            }
            return xmlString;
        }

        /// <summary>
        /// Returns an object of type (T) based on descrialization of the string provided
        /// </summary>
        /// <see cref="System.IO.StringReader"/>
        /// <param name="stringToDeserialize"></param>
        /// <returns>object of type (T)</returns>
        public T deserializeFromString(string stringToDeserialize)
        {
            StringReader sr = new StringReader(stringToDeserialize);
            return (T)this.XmlSerializer.Deserialize(sr);
        }
        #endregion

        #region Events
        #endregion

        #region Interface Implementations
        #endregion
    }
}
